package com.cskaoyan.object01.syntax.block;

/*

代码块: 在Java中，使用{}括起来的代码被称为代码块，根据其位置和声明的不同
       可以分为局部代码块，构造代码块，静态代码块，同步代码块(多线程讲解)

   对于每种代码块，需要重点掌握，定义位置和声明方法 执行时机

   1）局部代码块(知道)
      定义:  方法体中定义的代码块
      执行时机:  随着方法的执行而执行
      作用：限定变量生命周期，及早释放，提高内存利用率(扯淡, 带来的内存利用率的优化可以忽略不计)
           从代码的可读性的角度，不推荐大家从内存利用率的角度使用局部代码块

      在嵌套的作用域中，不能定义同名局部变量，在没有嵌套关系的不同的代码块中，可以定义同名变量

    2） 构造代码块(初始化代码块)
      定义: 定义在类中方法体之外
      执行时机: 创建对象的时候执行, 并且每次创建对象都会执行
      作用:
        1.多个构造方法方法中相同的代码可以放在构造代码快，每次创建对象都会执行
        2.如果有代码，在每次创建对象时都执行，并且构造方法前执行

        构造方法 VS 构造代码块 构造代码块优先于构造方法执行
        从给对象成员变量初始化的角度，总结一下，有三种方式在创建对象的过程种，给对象的成员变量赋初值
        1. 构造方法
        2. 构造代码块
        3. 成员变量的初始化语句

        构造代码块 优先于 构造方法执行
        成员变量的初始化语句 优先于 构造方法执行
        构造代码块 VS 初始化语句：
           a.它们并没有固定的先后顺序，按照代码书写的先后来决定，谁在前先执行谁
           b.但是习惯上，我们会把成员变量的初始化语句写在构造代码块之前，所以通常
             初始化语句优先于构造代码块执行


        3） 静态代码块
        定义:  定义在类种方法体之外，被static修饰
        执行时机：随着类加载而执行，因为一个类的加载正常情况下在一个jvm只会发生一次
                  静态代码块，在一个jvm中最多执行一次

        作用: 有些场景下，有些代码我们仅仅只需要执行一次，这种代码可以放在静态代码块中执行
        注意事项:
           静态代码块也属于静态上下文的一种



 */
public class Demo1 {

    public static void main(String[] args) {

        // 创建对象
        BlockClass first = new BlockClass();
        //System.out.println(first.memberField);

        //BlockClass second = new BlockClass();
    }



}


class BlockClass {

    // 成员变量的初始化语句
    int memberField = 2000;

    // 构造代码块
    {
        memberField = 100;
        System.out.println("init code block");
    }

    // static context
    // 静态代码块
   static  {

        // 不能访问非静态的成员变量
        //System.out.println(memberField);

        // 不能访问非静态成员方法
        //localMethod();

        System.out.println("static code block");
    }





    public BlockClass() {
        // 一段代码
        //memberField = 1000;
        //System.out.println("BlockClass");
    }



    public void localMethod() {
        int b = 10;
        // 局部代码块
        {
            // 只要执行完了变量的作用域，变量的存储空间就会被回收
            int a = 10;
            System.out.println(a);
            System.out.println(b);


            // 在嵌套的作用域中，不能定义同名局部变量
            //int b = 90;
        }


        {
            // 在没有嵌套关系的不同的作用域中，可以定义同名局部变量
            int a = 100;
            System.out.println(a);

        }

        // 在变量声明的作用域之外
        //System.out.println(a);

    }




}
